package com.app.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.base.Preconditions;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * Created by Lichaojie on 2017/3/4. It's a beautiful day.
 */

/**
 * @Bean 注解会告诉Spring这个方法将会返回一个对象，该对象要注册为Spring应用上下文中的bean。方法体包含了最终产生bean实例的逻辑。
 */
@Configuration
@EnableAutoConfiguration
@EnableTransactionManagement
public class MyBatisConfig implements ApplicationContextAware{
    ///这个接口可以用于获取spring上下文中定义的所有bean
    @Autowired
    private Environment env;

    private ApplicationContext context;

    /**
     * 数据库配置信息
     */
    private static final String MYBATIS_DB_URL = "mybatis.db.url";
    private static final String MYBATIS_DB_USERNAME = "mybatis.db.username";
    private static final String MYBATIS_DB_PASSWORD = "mybatis.db.password";
    private static final String MYBATIS_DB_MAX_ACTIVE = "mybatis.db.maxActive";
    /**
     * Mappers.mybatis 数据库配置
     */
    // Mappers.mybatis data source
    @Bean(name = "mybatisDS")
    @Qualifier("mybatisDS")
    @Primary
    public DruidDataSource mybatisDS() {

        final String url = Preconditions.checkNotNull(env.getProperty(MYBATIS_DB_URL));
        final String username = Preconditions.checkNotNull(env.getProperty(MYBATIS_DB_USERNAME));
        final String password = env.getProperty(MYBATIS_DB_PASSWORD);
        final int maxActive = Integer.parseInt(env.getProperty(MYBATIS_DB_MAX_ACTIVE, "200"));

        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setMaxActive(maxActive);

        return dataSource;
    }

    // Mappers.mybatis session factory
    @Bean(name = "mybatisFactory")
    @Qualifier("mybatisFactory")
    public SqlSessionFactory sqlSessionFactorySso() throws Exception {

        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(mybatisDS());//使用之前的datasource
        factoryBean.setMapperLocations(context.getResources("classpath*:mappers/**/dao/*.xml"));//配置了mapper的地址
        factoryBean.setConfigLocation(context.getResource("classpath:mybatis-config.xml"));
        return factoryBean.getObject();//一个sqlsessionfactory就可以操作mapper里面定义的操作了
    }

    // Mappers.mybatis transaction manager
    @Bean(name = "mybatisManager")
    @Qualifier("mybatisManager")
    public DataSourceTransactionManager transactionManagerPrimary() {

        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(mybatisDS());
        transactionManager.setRollbackOnCommitFailure(true);
        return transactionManager;//配置事物管理器
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
}
